import {
	ab2hex
} from '../codec/util.js';

export default {
	methods: {
		// 开启适配器
		openAdapter() {
			const that = this;

			uni.showLoading({
				title: '开启适配器...',
				mask: true
			});

			that.$store.commit('adapter/updateStatus', 1);

			plus.bluetooth.openBluetoothAdapter({
				success(res) {
					that.$store.commit('adapter/updateStatus', 2);
				},
				fail(errr) {
					uni.showModal({
						title: '开启适配器失败',
						content: JSON.stringify(err),
						showCancel: false
					});
				},
				complete() {
					uni.hideLoading();
				}
			});
		},
		// 搜寻附近的蓝牙外围设备
		startDiscovery() {
			const that = this;

			uni.showLoading({
				title: '开始扫描设备...'
			});

			// 清空已扫描设备列表
			that.clearScanned();

			that.$store.commit('adapter/updateStatus', 3);

			plus.bluetooth.startBluetoothDevicesDiscovery({
				// 获取设备的uuid列表
				services: ['FE60'],
				allowDuplicatesKey: true,
				success(res) {
					that.onDeviceFound();
				},
				fail(errr) {
					uni.showModal({
						title: '开启扫描失败',
						content: JSON.stringify(err),
						showCancel: false
					});
				},
				complete() {
					uni.hideLoading();
				}
			});
		},
		// 监听寻找到新设备
		onDeviceFound() {
			const that = this;

			plus.bluetooth.onBluetoothDeviceFound((res) => {
				that.addScanned(res.devices.filter(d => d.name || d.localName));
			});
		},
		// 创建连接
		createConnection(device, callback) {
			const that = this;

			uni.showLoading({
				title: '开始连接设备...',
				mask: true
			});

			plus.bluetooth.createBLEConnection({
				deviceId: device.id,
				success(res) {
					uni.hideLoading();

					uni.showToast({
						title: '设备连接成功',
						icon: 'success'
					});

					// 日志
					that.addOprLog({
						type: 'success',
						title: '设备连接',
						content: '成功 => ' + device.name
					});

					// 保存设备信息
					uni.setStorageSync('deviceId', device.id);
					uni.setStorageSync('deviceName', device.name);

					// 同步连接状态
					that.syncConnectedStatus();

					// 添加历史列表
					that.addHistory(device);

					callback && callback();
				},
				fail(err) {
					uni.hideLoading();

					uni.showModal({
						title: '连接设备失败',
						content: JSON.stringify(err),
						showCancel: false
					});
				},
				complete() {
					that.stopDiscovery();
				}
			});
		},
		// 设置MTU
		setMTU(deviceId, callback) {
			const that = this;

			uni.showLoading({
				title: '开始设置MTU...',
				mask: true
			});

			setTimeout(() => {
				plus.bluetooth.setBLEMTU({
					deviceId,
					mtu: 200,
					success(res) {
						uni.hideLoading();

						// 日志
						that.addOprLog({
							type: 'success',
							title: '设置MTU',
							content: '成功'
						});

						callback && callback();
					},
					fail(err) {
						uni.hideLoading();

						uni.showModal({
							title: '设置MTU失败',
							content: JSON.stringify(err),
							showCancel: false
						});
					}
				});
			}, 2000);
		},
		// 获取设备服务
		getDeviceServices(deviceId) {
			const that = this;

			uni.showLoading({
				title: '获取设备服务...',
				mask: true
			});

			setTimeout(() => {
				plus.bluetooth.getBLEDeviceServices({
					deviceId,
					success(res) {
						uni.hideLoading();

						const services = res.services;

						let serviceId;
						for (let i = 0, len = services.length; i < len; i++) {
							if (services[i].uuid.startsWith('0000FE60') && services[i].isPrimary) {
								serviceId = services[i].uuid;
								break;
							}
						}
						if (serviceId) {
							// 保存设备服务特征值
							uni.setStorageSync('serviceId', serviceId);

							that.getDeviceCharacteristics(deviceId, serviceId);
						}
					},
					fail(err) {
						uni.hideLoading();

						uni.showModal({
							title: '获取设备服务失败',
							content: JSON.stringify(err),
							showCancel: false
						});
					}
				});
			}, 2000);
		},
		// 获取设备特征值
		getDeviceCharacteristics(deviceId, serviceId) {
			const that = this;

			uni.showLoading({
				title: '获取服务特征值...',
				mask: true
			});

			plus.bluetooth.getBLEDeviceCharacteristics({
				deviceId,
				serviceId,
				success(res) {
					uni.hideLoading();

					const characteristics = res.characteristics;

					let characteristic, canNotify = false,
						canWrite = false;
					for (let i = 0, len = characteristics.length; i < len; i++) {
						characteristic = characteristics[i];

						// 可监听
						if (!canNotify && (characteristic.properties.notify || characteristic.properties
								.indicate)) {
							canNotify = true;

							// 保存设备监听特征值
							uni.setStorageSync('characteristicId.read', characteristic.uuid);

							// 启用低功耗蓝牙设备特征值变化时的 notify 功能，订阅特征值
							that.notifyCharacteristicsValueChange(deviceId, serviceId, characteristic.uuid);
						}

						// 可写
						if (!canWrite && characteristic.properties.write) {
							canWrite = true;

							// 保存设备读特征值
							uni.setStorageSync('characteristicId.write', characteristic.uuid);
						}
					}
				},
				fail(err) {
					uni.hideLoading();

					uni.showModal({
						title: '获取服务特征值失败',
						content: JSON.stringify(err),
						showCancel: false
					});
				}
			});
		},
		// 开启特征值变化监听
		notifyCharacteristicsValueChange(deviceId, serviceId, characteristicId) {
			const that = this;

			plus.bluetooth.notifyBLECharacteristicValueChange({
				deviceId,
				serviceId,
				characteristicId,
				state: true,
				success(res) {
					// 日志
					that.addOprLog({
						type: 'success',
						title: '开启监听',
						content: '成功'
					});

					that.onCharacteristicsValueChange();
				},
				fail(err) {
					uni.showModal({
						title: '开启特征值监听失败',
						content: JSON.stringify(err),
						showCancel: false
					});
				}
			});
		},
		// 监听特征值变化
		onCharacteristicsValueChange() {
			const that = this;

			uni.showToast({
				title: '开始数据监听',
				icon: 'success'
			});

			plus.bluetooth.onBLECharacteristicValueChange((res) => {
				uni.showToast({
					title: '接收到设备数据',
					icon: 'success'
				});

				// 日志
				that.addOprLog({
					type: 'info',
					title: '监听特征值',
					content: ab2hex(res.value)
				});
			});
		},
		// 写入特征值
		writeCharacteristicValue(deviceId, buffer) {
			const that = this;

			const serviceId = uni.getStorageSync('serviceId');
			const characteristicId = uni.getStorageSync('characteristicId.write');
			if (!serviceId || !characteristicId) {
				uni.showModal({
					title: '写入特征值',
					content: '请先获取服务特征值',
					showCancel: false
				});
				return;
			}

			plus.bluetooth.writeBLECharacteristicValue({
				deviceId,
				serviceId,
				characteristicId,
				value: buffer,
				success(res) {
					uni.showModal({
						title: '写入特征值成功',
						content: res.message,
						showCancel: false
					});

					// 日志
					that.addOprLog({
						type: 'success',
						title: '写入特征值',
						content: '成功 => ' + ab2hex(buffer)
					});
				},
				fail(err) {
					uni.showModal({
						title: '写入特征值失败',
						content: JSON.stringify(err),
						showCancel: false
					});

					// 日志
					that.addOprLog({
						type: 'warn',
						title: '写入特征值',
						content: '失败 => ' + JSON.stringify(err)
					});
				}
			});
		},
		// 断开设备连接
		disconnectDevice(deviceId, deviceName, callback) {
			const that = this;

			uni.showLoading({
				title: '开始断开设备连接...',
				mask: true
			});

			plus.bluetooth.closeBLEConnection({
				deviceId,
				success(res) {
					uni.hideLoading();

					uni.showToast({
						title: '设备已断开',
						icon: 'success'
					});
					// 日志
					that.addOprLog({
						type: 'success',
						title: '设备断开',
						content: '成功 => ' + deviceName
					});

					// 移除设备相关缓存：
					// deviceId，
					// deviceName，
					// serviceId，
					// characteristicId.read，
					// characteristicId.write
					uni.clearStorageSync();

					// 同步连接状态
					that.syncConnectedStatus();

					callback && callback();
				},
				fail(err) {
					uni.hideLoading();

					uni.showModal({
						title: '断开连接失败',
						content: JSON.stringify(err),
						showCancel: false
					});
				}
			});
		},
		// 停止搜寻附近的蓝牙外围设备
		stopDiscovery() {
			const that = this;

			plus.bluetooth.stopBluetoothDevicesDiscovery({
				success(res) {
					that.$store.commit('adapter/updateStatus', 2);
				},
				fail(err) {
					uni.showModal({
						title: '停止扫描失败',
						content: JSON.stringify(err),
						showCancel: false
					});
				}
			})
		},
		// 关闭适配器
		closeAdapter() {
			const that = this;

			// 清空已扫描设备列表
			that.clearScanned();

			plus.bluetooth.closeBluetoothAdapter({
				success(res) {
					that.$store.commit('adapter/updateStatus', 0);

					// 移除设备相关缓存：
					// deviceId，
					// deviceName，
					// serviceId，
					// characteristicId.read，
					// characteristicId.write
					uni.clearStorageSync();
				},
				fail(err) {
					uni.showModal({
						title: '关闭适配器失败',
						content: JSON.stringify(err),
						showCancel: false
					});
				}
			});
		}
	}
}
